今天我們要來討論的是變數及函式等在程式中需要我們自行命名的部分,一個很多人都心照不宣的不成文規定,那就是命名規則 (Naming Convention)。
首先,我們必須要知道的是,它只是一個不成文規定,因此實際上並沒有一個很準確的標準,我們也可以不去遵守,一切都是看個人的喜好跟意願。命名規則一直很具爭議性的點就在於,它會隨著不同的程式語言、環境、組織或公司、派系等而有不同的變化,甚至是同一批人在使用相同的程式語言也有可能會隨著時間因為改變了個人習慣而改變了命名規則。那麼我們為什麼還要認識並嘗試遵守它呢?這是因為它是一種工程師之間的溝通方式,在遵守良好的命名規則的情況下,工程師能快速的透過變數及函式的名稱來理解到它們大概的用途而不需要花費更多的時間來查詢相關的程式碼後才能了解。因此,大多數的工程師,尤其是業界的人士,都會遵循一套命名規則來為變數及函式等命名。
正如前文所述,詳細的命名規則會隨著不同的因素而有各式各樣的變化,所以大家還是需要在使用前先進行了解應該使用什麼命名規則,尤其是在團隊合作時需要事先進行溝通或是參考前輩的寫法。不過,一般的命名規則都是由某些特定的命名方式或原則所組成,因此今天會為大家介紹一些常見的命名方式或原則,讓大家可以參考一下。
1. 把用途寫出來
既然命名的其中一個目的是為了與其他人溝通,那麼我們當然需要讓變數及函式等的名稱是有著某種跟它的用途有關的意思,而且最好是能讓人一看到就能理解。舉例來說,如果我們今天要做一個計算從 1 加到 n 的加總的程式:
(A)
public static int a(int b) {
int c = 0;
for (int i = 1; i <= b; i++) {
c += b;
}
return c;
}
(B)
public static int getSum(int n) {
int sum = 0;
for (int i = 1; i <= n; i++) {
sum += n;
}
return sum;
}
無論 (A) 跟 (B) 的寫法在運行時都能回傳一樣的結果,可是 (B) 的寫法就能讓人更好的理解到每一個變數、參數跟函數各自在程式中有什麼的用途。相對的,(A) 的寫法不但沒辦法從名稱知道它們的用途,更會在程式變得複雜的時候為工程師帶來不必要的混亂。
2. 名稱不要太長,減少使用不必要的用字
當我們要命名時,為了可以清晰的表達它的用途,那我們是不是應該把所有相關的資訊都寫出來呢?答案是可以不寫就不寫,這是因為當變數及函式等的名稱過長時,反而會影響到我們的閱讀,我們來比較一下下面的例子:
(A)
int theTotalSumOfNNumbers = calculateTheTotalSumOfNNumbers(theCountOfNumbers);
(B)
int sum = getSum(n);
很明顯,(A) 的寫法所包含的資訊量必然比 (B) 更多更詳細,可是像這樣一大串的字都擠在一起時,我們真的能一下子就理解一整串句子的含意嗎?相對的,(B) 的寫法雖然比較簡短,卻已經把最關鍵的資訊寫出來,最少我們已經可以看出這個變數跟函式都是跟加總有關。不過,當有多個具相似用途的變數或函式時,我們便需要增加名字中的資訊來讓我們可以把它們區分開來。
3. 避開關鍵字/保留字
在每一種程式語言中,都必定會有保留字 (Reserved Words)。保留字是一些被程式語言視為具有特別含意的單字,例如陳述式中常使用的 if、else、while、for 等,由於這些單字通常都代表著一些程式的邏輯,因此我們不能單獨使用這些單字來當作我們的變數及函式等的名稱。需要注意的是,每一種程式語言所包含的保留字都不一樣,因此大家在使用程式語言前可以先到官方文檔查詢一下有什麼保留字。
4. 善用代表單複數的用字
我們可以使用單複數的用字來快速區分儲存單項資料的變數與儲存多項資料的陣列,舉例來說,當我們需要儲存數字時,可以使用 num 來表示變數及 nums 來表示陣列。
5. 具一致性
在同一個程式中表示同樣的資訊時我們應該使用相同的單字,這樣可以避免我們在後續的程式中不會因為變數及函式名稱的用字而陷入混亂。
舉例來說,假如我們一開始有以下的變數來儲存用戶資訊:
userID, userName, userPassword
當我們要新增一個新的變數來儲存用戶的年齡 (age) 時,我們應該使用 userAge 而不是 age 或是 accountAge 之類的名稱,這樣可以幫助我們確認這個變數跟用戶資訊有關。
1. 駝峰式命名法 (Camel Case)/Pascal 命名法 (Pascal Case)
駝峰式命名法是最常被使用的命名方式。它的規則是當名稱中包含多於一個單詞時,不使用空格,把單詞的開頭以大寫表示來區別不同的單詞。同時,駝峰式命名法的第一個單詞的開頭會使用小寫,例如:
getSum (get sum)、userName (user name)
駝峰式命名法有一種延伸的變體,是把第一個單詞的開頭也使用大寫,這種命名方式被稱為 Pascal 命名法,例如:
GetSum (get sum)、UserName (user name)
2. Snake Case 命名法/Screaming Case 命名法/Kebab Case 命名法
Snake Case 命名法是當名稱中包含多於一個單詞時,以底線代替空格來把整串的句子連在一起,所有的字都是以小寫來表示,這命名法常用於 Python 的程式中。例如:
get_sum (get sum)、user_name (user name)
Snake Case 命名法有一種被稱為 Screaming Case 命名法的延伸變體。Screaming Case 命名法是把所有的字都以大寫來表示,例如:
GET_SUM (get sum)、USER_NAME (user name)
而另一種Snake Case 命名法的延伸變體則是 Kebab Case 命名法。Kebab Case 命名法則是以連字符 (-) 代替空格,所有的字也同樣是以小寫來表示,例如:
get-sum (get sum)、user-name (user name)
3. 匈牙利命名法 (Hungarian notation)
匈牙利命名法是在變數命名時將資料型態放在最前面,再以駝峰式命名法的方式把資料型態跟名稱合併在一起,是較早期使用的命名法,現在已經很少被使用。例如:
intGetSum (int 資料型態的 get sum)、strUserName/stringUserName (string 資料型態的 user name)
以上介紹了變數及函式等的名稱的一些常見的命名原則及命名方式,再次提醒大家需要注意的是:命名規則通常都不是只包含一種命名原則或命名方式,而是根據命名的對象、種類、用途等視情況而把多項命名原則跟命名方式混合在一起使用。其中一個例子便是在 c 語言中,通常會使用 Screaming Case 命名法來命名常數,並使用駝峰式命名法來命名變數。因此,多了解不同的命名原則及命名方式才能配合不同的情況使用不同的命名規則。